#pragma once

#include "TCPConnection.hh"
#include <map>
#include <memory>
#include <sys/epoll.h>
#include <vector>
using std::map;
using std::shared_ptr;
using std::vector;

namespace wd
{
class Acceptor;

// epoll：1 创建epollfd，2 注册要监听的描述符，3 等待描述符就绪
class EventLoop
{
  public:
    EventLoop(Acceptor &); // peerfd,sockfd
    void loop();
    void unloop();
    
    // 回调函数，转交给TCPConnection对象
    void setConnectionCallback(TCPCallback &&cb);
    void setMessageCallback(TCPCallback &&cb);
    void setCloseCallback(TCPCallback &&cb);

  private:
    int epollCreate();           // 1 创建epollfd
    void addEpollFdRead(int fd); // 2 注册需要监听的描述符
    void delEpollFdRead(int fd);
    void epollWait(); // 3 等待描述符就绪
    // epoll_wait的2种情况：1 新连接到来；2 与旧连接通信
    void handleNewConnection();        // 新连接到来。干几件事：1 注册peerfd 2 创建新连接，调用回调函数 3 新连接存入map
    void handleNewMessage(int peerfd); // 与对端通信
    bool isConnectClosed(int fd);      // 连接是否关闭

  private:
    int _epfd;
    Acceptor &_acceptor; // 获取socketfd和peerfd
    vector<struct epoll_event> _eventList;

    // using TCPConnectionPtr = shared_ptr<TCPConnection>;
    // 用map存储TCP连接  {peerfd: tcp*} 存指针避免复制
    map<int, TCPConnectionPtr> _conns;
    bool _isLooping;

    // 回调函数，传给TCPConnection对象
    // using TCPCallback = function<void(const TCPConnectionPtr &)>;
    TCPCallback _onConnection;
    TCPCallback _onMessage;
    TCPCallback _onClose;
};

} // end of namespace wd